package ConCurrent;

/**
 * 实现线程之间的交替打印
 *
 * 思路： 使用wait()和notify()方法， synchrinized关键字和 volatile变量
 *      synchrinized锁同步块，
 *      volatile变量保证可见性，用于判断条件哪个线程进行执行。
 */
public class ThreadSwitch {
    private static volatile Object lock = new Object();
    private static volatile  int flag = 0;

    public static void main(String[] args) {

        Thread threadA = new Thread(() -> {
            while (true){
                // 同步代码块
                synchronized (lock){
                    // flag不为0时，则阻塞
                    while (flag != 0){
                        try {
                            lock.wait();
                        } catch (InterruptedException e) {
                            throw new RuntimeException(e);
                        }
                    }
                    System.out.println("A---start");
                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        throw new RuntimeException(e);
                    }
                    flag = 1; // 切换到线程B执行
                    lock.notifyAll(); // 通知所有线程
                }
            }
        }, "ThreadA");

        Thread threadB = new Thread(() -> {
            while (true){
                synchronized (lock){
                    while (flag != 1){
                        try {
                            lock.wait();
                        } catch (InterruptedException e) {
                            throw new RuntimeException(e);
                        }
                    }
                    System.out.println("B---start");
                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        throw new RuntimeException(e);
                    }
                    flag =2; // 切换到线程C执行
                    lock.notifyAll();
                }

            }
        },"ThreadB");

        Thread threadC = new Thread(() -> {
            while (true){
                synchronized (lock){
                    while (flag != 2){
                        try {
                            lock.wait();
                        } catch (InterruptedException e) {
                            throw new RuntimeException(e);
                        }
                    }
                    System.out.println("C---start");
                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        throw new RuntimeException(e);
                    }
                    flag =0; // 切换到线程A执行
                    lock.notifyAll();
                }
            }
        }, "ThreadC");

        threadA.start();
        threadB.start();
        threadC.start();
    }
}
